package com.rtc.call.core

import android.annotation.SuppressLint
import android.content.Context
import android.content.SharedPreferences
import android.util.Log
import com.rtc.call.core.data.ConfigResponse
import com.rtc.call.core.data.request.ConfigRequest
import com.rtc.call.core.network.repository.ConfigRepository
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch

/**
 * Manages configuration files for different modes without caching or asset reading.
 */
class ConfigManager(private val context: Context) {
    private val TAG = "ConfigManager"

    private val repository = ConfigRepository(context)
    
    // SharedPreferences for storing configuration
    private val prefs: SharedPreferences = context.getSharedPreferences("agora_call_config", Context.MODE_PRIVATE)


    var nfcId = ""
    var lastNfcId = ""

    companion object {

        // Config types
        const val CONFIG_TYPE_TURNON = "TURNON"
        const val CONFIG_TYPE_NFCON = "NFCON"
        const val CONFIG_TYPE_NFCOFF = "NFCOFF"
        const val CONFIG_TYPE_SLEEP = "SLEEP"
        const val CONFIG_TYPE_WAKEUP = "WAKEUP"
        const val CONFIG_DEVICE_ID = "device_id"

    }

    // Current configurations
    private var turnOnConfig: ConfigResponse? = null
    private var nfcOnConfig: ConfigResponse? = null
    private var nfcOffConfig: ConfigResponse? = null
    
    // State flows for configuration states
    private val _turnOnConfigState = MutableStateFlow<Result<ConfigResponse>?>(null)
    val turnOnConfigState: StateFlow<Result<ConfigResponse>?> = _turnOnConfigState
    
    private val _nfcOnConfigState = MutableStateFlow<Result<ConfigResponse>?>(null)
    val nfcOnConfigState: StateFlow<Result<ConfigResponse>?> = _nfcOnConfigState
    
    private val _nfcOffConfigState = MutableStateFlow<Result<ConfigResponse>?>(null)
    val nfcOffConfigState: StateFlow<Result<ConfigResponse>?> = _nfcOffConfigState


    private val _configState = MutableStateFlow<Result<ConfigResponse>?>(null)
    val configState: StateFlow<Result<ConfigResponse>?> = _configState

    /**
     * Load TURNON configuration from backend
     */
    fun loadTurnOnConfig(coroutineScope: CoroutineScope) {
        val request = ConfigRequest()
        request.status = CONFIG_TYPE_TURNON
        request.devId = getDeviceId(context)
        request.lastNfcId = ""
        request.nfcId = ""
        request.version = "BASE_0.0.1"
        request.agoraRequest = "1"
        fetchConfig(coroutineScope, request) { result ->
            _turnOnConfigState.value = result
            _configState.value = result
            result.getOrNull()?.let { turnOnConfig = it }
        }
    }

    /**
     * Load NFCON configuration from backend
     */
    fun loadNfcOnConfig(coroutineScope: CoroutineScope,lastNfcId: String?,nfcId: String?, appId: String?,channel:String?,token:String?) {

        val request = ConfigRequest()
        request.status = CONFIG_TYPE_NFCON
        request.devId = getDeviceId(context)
        request.lastNfcId = lastNfcId.orEmpty()
        request.nfcId = nfcId.orEmpty()
        request.version = "BASE_0.0.1"

        request.agoraToken = token.orEmpty()
        request.agoraChannel = channel.orEmpty()
        request.agoraAppId = appId.orEmpty()
        fetchConfig(coroutineScope, request) { result ->
            _nfcOnConfigState.value = result
            _configState.value = result
            result.getOrNull()?.let { nfcOnConfig = it }
        }
    }

    /**
     * Load NFCOFF configuration from backend
     */
    fun loadNfcOffConfig(coroutineScope: CoroutineScope,lastNfcId: String?,nfcId: String?, appId: String?,channel:String?,token:String?) {
        val request = ConfigRequest()
        request.status = CONFIG_TYPE_NFCOFF
        request.devId = getDeviceId(context)
        request.lastNfcId = lastNfcId.orEmpty()
        request.nfcId = nfcId.orEmpty()
        request.version = "BASE_0.0.1"

        request.agoraToken = token.orEmpty()
        request.agoraChannel = channel.orEmpty()
        request.agoraAppId = appId.orEmpty()
        fetchConfig(coroutineScope, request) { result ->
            _nfcOffConfigState.value = result
            _configState.value = result
            result.getOrNull()?.let { nfcOffConfig = it }
        }
    }

    /**
     * Fetch configuration using the repository
     */
    private fun fetchConfig(
        coroutineScope: CoroutineScope,
        request :ConfigRequest,
        onResult: (Result<ConfigResponse>) -> Unit
    ) {
        coroutineScope.launch {

            repository.getConfig(request).collectLatest { result ->
                Log.d(TAG, "Fetched config for type: ${request.status}, result: $result")
                onResult(result)
            }
        }
    }

    /**
     * Set configurations directly (for testing or fallback)
     */
    fun setTurnOnConfig(config: ConfigResponse) {
        turnOnConfig = config
        _turnOnConfigState.value = Result.success(config)
    }

    fun setNfcOnConfig(config: ConfigResponse) {
        nfcOnConfig = config
        _nfcOnConfigState.value = Result.success(config)
    }

    fun setNfcOffConfig(config: ConfigResponse) {
        nfcOffConfig = config
        _nfcOffConfigState.value = Result.success(config)
    }



    /**
     * Get channel ID from configuration
     */
    fun getChannelId(configType: String): String {
        return when (configType) {
            CONFIG_TYPE_TURNON -> turnOnConfig?.agoraChannel
            CONFIG_TYPE_NFCON -> nfcOnConfig?.agoraChannel
            CONFIG_TYPE_NFCOFF -> nfcOffConfig?.agoraChannel
            else -> turnOnConfig?.agoraChannel
        } ?: "default_channel"
    }

    /**
     * Get Agora app ID from configuration
     */
    fun getAppId(configType: String): String {
        return when (configType) {
            CONFIG_TYPE_TURNON -> turnOnConfig?.agoraAppId
            CONFIG_TYPE_NFCON -> nfcOnConfig?.agoraAppId
            CONFIG_TYPE_NFCOFF -> nfcOffConfig?.agoraAppId
            else -> turnOnConfig?.agoraAppId
        } ?: ""
    }

    /**
     * Get token from configuration
     */
    fun getToken(configType: String): String? {
        return when (configType) {
            CONFIG_TYPE_TURNON -> turnOnConfig?.agoraToken
            CONFIG_TYPE_NFCON -> nfcOnConfig?.agoraToken
            CONFIG_TYPE_NFCOFF -> nfcOffConfig?.agoraToken
            else -> turnOnConfig?.agoraToken
        }
    }

    fun getGreetingSoundFile(): String? {
        //
        return "";
    }

    /**
     * Get audio enabled setting from configuration
     */
    fun isAudioEnabled(configType: String): Boolean {
        return true
    }

    /**
     * Get video enabled setting from configuration
     */
    fun isVideoEnabled(configType: String): Boolean {
        return false
//        return when (configType) {
//            CONFIG_TYPE_TURNON -> turnOnConfig?.videoEnabled
//            CONFIG_TYPE_NFCON -> nfcOnConfig?.videoEnabled
//            CONFIG_TYPE_NFCOFF -> nfcOffConfig?.videoEnabled
//            else -> turnOnConfig?.videoEnabled
//        } ?: true
    }

    /**
     * Get speaker enabled setting from configuration
     */
    fun isSpeakerEnabled(configType: String): Boolean {
        return  true
    }

    /**
     * Get volume level from configuration
     */
    fun getVolumeLevel(configType: String): Int {
        return 50

    }

    /**
     * Get colorful mode setting from configuration
     */
    fun isColorfulModeEnabled(configType: String): Boolean {
        return false

    }

    /**
     * Get light enabled setting from configuration
     */
    fun isLightEnabled(configType: String): Boolean {
        return false

    }

    /**
     * Get greeting sound file from configuration
     */
    fun getGreetingSoundFile(configType: String): String? {
        return ""

    }

    /**
     * Get ending sound file from configuration
     */
    fun getEndingSoundFile(configType: String): String? {
        return ""
//        return when (configType) {
//            CONFIG_TYPE_TURNON -> turnOnConfig?.endingSound
//            CONFIG_TYPE_NFCON -> nfcOnConfig?.endingSound
//            CONFIG_TYPE_NFCOFF -> nfcOffConfig?.endingSound
//            else -> turnOnConfig?.endingSound
//        }
    }

    @SuppressLint("HardwareIds")
     fun getDeviceId(context: Context): String {
         val deviceId = prefs.getString(CONFIG_DEVICE_ID,"3351e12d926e62ca")
        Log.d(TAG,"prefs getDeviceId = $deviceId")
//         return deviceId.orEmpty()
        return "3351e12d926e62ca"
//        return Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
    }

    @SuppressLint("UseKtx")
    fun saveDeviceId(deviceId: String) {
        prefs.edit().putString(CONFIG_DEVICE_ID, deviceId).apply()
    }
} 